﻿using FluentRestSharp.Interface;
using RestSharp;
using RestSharp.Authenticators;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace FluentRestSharp.Impl
{
    public class FluentClient : IFluentClient
    {
        public RestClient RestClient => restClient;
        private RestClient restClient;
        private List<(string name, string value)> defaultHeaderList = new List<(string name, string value)>();
        private List<(string name, string value)> defaultParameterList = new List<(string name, string value)>();
        private List<(string name, string value)> defaultQueryParameter = new List<(string name, string value)>();
        private List<(string name, string value)> defaultUrlSegment = new List<(string name, string value)>();


        public IFluentClient AddDefaultHeader(string name, string value)
        {
            defaultHeaderList.Add((name, value));
            return this;
        }


        public IFluentClient AddDefaultParameter(string name, string value)
        {
            defaultParameterList.Add((name, value));
            return this;
        }


        public IFluentClient AddDefaultQueryParameter(string name, string value)
        {
            defaultQueryParameter.Add((name, value));
            return this;
        }


        public IFluentClient AddDefaultUrlSegment(string name, string value)
        {
            defaultUrlSegment.Add((name, value));
            return this;
        }
		private FluentRequest AddClientParamters()
        {
			if (restClient == null)
			{
				throw new ArgumentNullException("client is null!");
			}
			foreach (var header in defaultHeaderList)
			{
				restClient.AddDefaultHeader(header.name, header.value);
			}
			foreach (var parameter in defaultParameterList)
			{
				restClient.AddDefaultParameter(parameter.name, parameter.value);
			}
			foreach (var queryParameter in defaultQueryParameter)
			{
				restClient.AddDefaultQueryParameter(queryParameter.name, queryParameter.value);
			}
			foreach (var item in defaultUrlSegment)
			{
				restClient.AddDefaultUrlSegment(item.name, item.value);
			}
			//if (authenticator != null)
			//{
			//	restClient.UseAuthenticator(authenticator);
			//}
			return new FluentRequest(restClient);
		}

        public IFluentRequest BuildClient(RestClientOptions options, ConfigureHeaders configureDefaultHeaders = null, ConfigureSerialization configureSerialization = null, bool useClientFactory = false)
        {
            restClient=new RestClient(options,configureDefaultHeaders,configureSerialization,useClientFactory);
            return AddClientParamters();
        }

        public IFluentRequest BuildClient(ConfigureRestClient configureRestClient = null, ConfigureHeaders configureDefaultHeaders = null, ConfigureSerialization configureSerialization = null, bool useClientFactory = false)
        {
            restClient = new RestClient(configureRestClient, configureDefaultHeaders, configureSerialization, useClientFactory);
            return AddClientParamters();
        }

        public IFluentRequest BuildClient(Uri baseUrl, ConfigureRestClient configureRestClient = null, ConfigureHeaders configureDefaultHeaders = null, ConfigureSerialization configureSerialization = null, bool useClientFactory = false)
        {
            restClient=new RestClient(baseUrl,configureRestClient,configureDefaultHeaders,configureSerialization,useClientFactory);
            return AddClientParamters();
        }

        public IFluentRequest BuildClient(string baseUrl, ConfigureRestClient configureRestClient = null, ConfigureHeaders configureDefaultHeaders = null, ConfigureSerialization configureSerialization = null)
        {
            restClient=new RestClient(baseUrl, configureRestClient,configureDefaultHeaders,configureSerialization);
            return AddClientParamters();
        }

        public IFluentRequest BuildClient(HttpClient httpClient, RestClientOptions options, bool disposeHttpClient = false, ConfigureSerialization configureSerialization = null)
        {
            restClient=new RestClient(httpClient, options, disposeHttpClient,configureSerialization);
            return AddClientParamters();
        }

        public IFluentRequest BuildClient(HttpClient httpClient, bool disposeHttpClient = false, ConfigureRestClient configureRestClient = null, ConfigureSerialization configureSerialization = null)
        {
            restClient = new RestClient(httpClient, disposeHttpClient, configureRestClient, configureSerialization);
            return AddClientParamters();
        }

        public IFluentRequest BuildClient(HttpMessageHandler handler, bool disposeHandler = true, ConfigureRestClient configureRestClient = null, ConfigureSerialization configureSerialization = null)
        {
            restClient=new RestClient(handler, disposeHandler, configureRestClient, configureSerialization);
            return AddClientParamters();
        }
    }
}
